package com.kr.aia.powerrp.dropbox;

import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.android.AuthActivity;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxIOException;
import com.dropbox.client2.exception.DropboxParseException;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.TokenPair;
import com.dropbox.client2.session.Session.AccessType;
import com.kr.aia.powerrp.R;
import com.kr.aia.powerrp.common.MainMovieClipListView;
import com.kr.aia.powerrp.dropbox.DropBoxLocalListView.VideoDataStruct;

public class DropBoxRP extends Activity implements OnClickListener{
	private static final String TAG = "TARP";

    ///////////////////////////////////////////////////////////////////////////
    //                      Your app-specific settings.                      //
    ///////////////////////////////////////////////////////////////////////////

    // Replace this with your app key and secret assigned by Dropbox.
    // Note that this is a really insecure way to do this, and you shouldn't
    // ship code which contains your key & secret in such an obvious way.
    // Obfuscation is good.
	final private String APP_KEY = "08h7sow4k673mba";
    final private String APP_SECRET = "hbf7674wz3chh2d";

    // If you'd like to change the access type to the full Dropbox instead of
    // an app folder, change this value.
    final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;

    ///////////////////////////////////////////////////////////////////////////
    //                      End app-specific settings.                       //
    ///////////////////////////////////////////////////////////////////////////

    // You don't need to change these, leave them alone.
    final static private String ACCOUNT_PREFS_NAME = "prefs";
    final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
    final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";


    DropboxAPI<AndroidAuthSession> mApi;

    private boolean mLoggedIn;
    
    
    private Button dropbox_btn_home;
    private Button btn_dropbox_go_parent;
    private Button btn_dropbox_upload;
    private Button btn_dropbox_download;
    
    private String mPath = "/";
    protected ListView dropboxServerView;
    protected static ArrayAdapter<DropBoxEntryVO> dropboxServerAdapter;
    private ArrayList<VideoDataStruct> tInfoList;
    private DropBoxLocalListView localListView;
    
    
    private String mErrorMsg;
    
    @Override
    public void onDestroy(){
    	super.onDestroy();
    }
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dropbox_main);
        
        
        dropbox_btn_home = (Button)findViewById(R.id.dropbox_btn_home);
        btn_dropbox_go_parent = (Button)findViewById(R.id.btn_dropbox_go_parent);
        btn_dropbox_upload = (Button)findViewById(R.id.btn_dropbox_upload);
        btn_dropbox_download = (Button)findViewById(R.id.btn_dropbox_download);
        dropboxServerView = (ListView)findViewById(R.id.dropbox_layout_server);
        
        // 클릭 리스너 등록
        dropbox_btn_home.setOnClickListener(this);
        btn_dropbox_go_parent.setOnClickListener(this);
        btn_dropbox_upload.setOnClickListener(this);
        btn_dropbox_download.setOnClickListener(this);
        
        checkAppKeySetup();
        
        // We create a new AuthSession so that we can use the Dropbox API.
        AndroidAuthSession session = buildSession();
        mApi = new DropboxAPI<AndroidAuthSession>(session);
        
        
        LinearLayout dropboxLayout = (LinearLayout)findViewById(R.id.dropbox_layout_local);
        localListView = new DropBoxLocalListView(this, "txt/rp", true);
		View dropboxLocalView = localListView.openMovieClipListView();
		
		tInfoList = localListView.getVideoListInfo();
        
		dropboxLayout.addView(dropboxLocalView);
		
		
		////////////////////////////////////////////////////////////////////////////////////////
		//// Show DropBox List
		////////////////////////////////////////////////////////////////////////////////////////
		
		dropboxServerAdapter = null;
		dropboxServerView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            	((DropBoxFolderListAdapter) dropboxServerAdapter).setSelectedItem(position);
            	
            	
            	if(((DropBoxFolderListAdapter) dropboxServerAdapter).isSelectedItem(position)){
            		((DropBoxFolderListAdapter) dropboxServerAdapter).setSelected(position, false);
        		}else{
        			((DropBoxFolderListAdapter) dropboxServerAdapter).setSelected(position, true);
        		}
            	
            	if(((DropBoxFolderListAdapter) dropboxServerAdapter).getSelectedItem(position).isDir){
            		mPath = mPath + ((DropBoxFolderListAdapter) dropboxServerAdapter).getSelectedItem(position).fileName() + "/";
            		showDropBoxList();
            	}
            	dropboxServerAdapter.notifyDataSetChanged();
            }
        });
		
		/*if (mApi.getSession().isLinked()) {
        	showDropBoxList();
        }*/
		
        /*
        Entry existingEntry;
		try {
			existingEntry = mApi.metadata("/", 1000, null, true, null);
			                //mApi.metadata(mPath, 1000, null, true, null);
			Log.i("DbExampleLog", "The file's rev is now: " + existingEntry.rev);
		} catch (DropboxUnlinkedException e) {
            // The AuthSession wasn't properly authenticated or user unlinked.
        } catch (DropboxPartialFileException e) {
            // We canceled the operation
            mErrorMsg = "Download canceled";
        } catch (DropboxServerException e) {
            // Server-side exception.  These are examples of what could happen,
            // but we don't do anything special with them here.
            if (e.error == DropboxServerException._304_NOT_MODIFIED) {
                // won't happen since we don't pass in revision with metadata
            } else if (e.error == DropboxServerException._401_UNAUTHORIZED) {
                // Unauthorized, so we should unlink them.  You may want to
                // automatically log the user out in this case.
            } else if (e.error == DropboxServerException._403_FORBIDDEN) {
                // Not allowed to access this
            } else if (e.error == DropboxServerException._404_NOT_FOUND) {
                // path not found (or if it was the thumbnail, can't be
                // thumbnailed)
            } else if (e.error == DropboxServerException._406_NOT_ACCEPTABLE) {
                // too many entries to return
            } else if (e.error == DropboxServerException._415_UNSUPPORTED_MEDIA) {
                // can't be thumbnailed
            } else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
                // user is over quota
            } else {
                // Something else
            }
            // This gets the Dropbox error, translated into the user's language
            mErrorMsg = e.body.userError;
            if (mErrorMsg == null) {
                mErrorMsg = e.body.error;
            }
        } catch (DropboxIOException e) {
            // Happens all the time, probably want to retry automatically.
            mErrorMsg = "Network error.  Try again.";
        } catch (DropboxParseException e) {
            // Probably due to Dropbox server restarting, should retry
            mErrorMsg = "Dropbox error.  Try again.";
        } catch (DropboxException e) {
            // Unknown error
            mErrorMsg = "Unknown error.  Try again.";
        }
		*/
    }
    
    
    @Override
    public void onClick(View v){
    	switch(v.getId()){
    		case R.id.dropbox_btn_home:
    			finish();
    			break;
    		case R.id.btn_dropbox_go_parent:
    			if(mPath.lastIndexOf("/") == 0){
    				Toast.makeText(this, "최상위 폴더입니다.", Toast.LENGTH_SHORT).show();
    			}else if(mPath.lastIndexOf("/") > 0){
    				mPath = mPath.substring(0, mPath.length()-1);
    				mPath = mPath.substring(0, mPath.lastIndexOf("/")+1);
    				
    				showDropBoxList();
    			}
    			//Log.e("PRP", "======================= " + mPath + " -- " + mPath.lastIndexOf("/"));
    			break;
    		case R.id.btn_dropbox_upload:
    			ArrayList<File> fileList = new ArrayList<File>();
    			tInfoList = localListView.getVideoListInfo();
    			
    			if(tInfoList != null && tInfoList.size() > 0){
    				for(int i = 0 ; i < tInfoList.size() ; i++){
    					
    					if(tInfoList.get(i).isSelected){
    						File uploadFile = new File(tInfoList.get(i).getFilePath());
    						fileList.add(uploadFile);
    					}
    				}
    				
    				DropBoxUpload upload = new DropBoxUpload(this, mApi, mPath, fileList, dropboxServerView);
	    			upload.execute();
    			}
    			
    			break;
    		case R.id.btn_dropbox_download:
    			ArrayList<String> dropboxList = new ArrayList<String>();
    			
    			int size = ((DropBoxFolderListAdapter) dropboxServerAdapter).getCount();
    			if(((DropBoxFolderListAdapter) dropboxServerAdapter) != null && size  > 0){
    				for(int i = 0 ; i < size ; i++){
    					//Log.e("PRP", (DropBoxFolderListAdapter) dropboxServerAdapter).get(i).getFilePath() + " -- " + tInfoList.get(i).isSelected);
    					
    					if(((DropBoxFolderListAdapter) dropboxServerAdapter).isSelectedItem(i) ){
    						String downloadFile = ((DropBoxFolderListAdapter) dropboxServerAdapter).getSelectedItem(i).fileName();
    						dropboxList.add(downloadFile);
    					}
    				}
    				
    				DropBoxDownload download = new DropBoxDownload(this, mApi, mPath, dropboxList, localListView);
                    download.execute();
    			}
    			
    			break;
    	}
    }
    
    
    
    @Override
    protected void onResume() {
        super.onResume();
        AndroidAuthSession session = mApi.getSession();

        // The next part must be inserted in the onResume() method of the
        // activity from which session.startAuthentication() was called, so
        // that Dropbox authentication completes properly.
        if (session.authenticationSuccessful()) {
            try {
                // Mandatory call to complete the auth
                session.finishAuthentication();

                // Store it locally in our app for later use
                TokenPair tokens = session.getAccessTokenPair();
                storeKeys(tokens.key, tokens.secret);
                //setLoggedIn(true);
                
                showDropBoxList();
                
            } catch (IllegalStateException e) {
                showToast("Couldn't authenticate with Dropbox:" + e.getLocalizedMessage());
                Log.i(TAG, "Error authenticating", e);
            }
        }
        
        if(session.isLinked()){
        	showDropBoxList();
        }else{
        	mApi.getSession().startAuthentication(DropBoxRP.this);
        }
    }
    
    public void showDropBoxList(){
        DropBoxFolerList folderview = new DropBoxFolerList(this, mApi, mPath, dropboxServerView);
        folderview.execute();
    }

    
    // This is what gets called on finishing a media piece to import
    
    /*
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == NEW_PICTURE) {
            // return from file upload
            if (resultCode == Activity.RESULT_OK) {
                Uri uri = null;
                if (data != null) {
                    uri = data.getData();
                }
                if (uri == null && mCameraFileName != null) {
                    uri = Uri.fromFile(new File(mCameraFileName));
                }
                File file = new File(mCameraFileName);

                if (uri != null) {
                    UploadPicture upload = new UploadPicture(this, mApi, mPath, file);
                    upload.execute();
                }
            } else {
                Log.w(TAG, "Unknown Activity Result from mediaImport: "
                        + resultCode);
            }
        }
        
        if (requestCode == DBX_CHOOSER_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                DbxChooser.Result result = new DbxChooser.Result(data);
                Log.d("main", "Link to selected file: " + result.getLink());

                // Handle the result
            } else {
                // Failed or was cancelled by the user.
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
    */

    private void logOut() {
        // Remove credentials from the session
        mApi.getSession().unlink();

        // Clear our stored keys
        clearKeys();
        // Change UI state to display logged out version
        //setLoggedIn(false);
    }

    /**
     * Convenience function to change UI state based on being logged in
     */
    /*
    private void setLoggedIn(boolean loggedIn) {
    	mLoggedIn = loggedIn;
    	if (loggedIn) {
    		mSubmit.setText("Unlink from Dropbox");
            mDisplay.setVisibility(View.VISIBLE);
    	} else {
    		mSubmit.setText("Link with Dropbox");
            mDisplay.setVisibility(View.GONE);
            mImage.setImageDrawable(null);
    	}
    }
    */

    private void checkAppKeySetup() {
        // Check to make sure that we have a valid app key
        if (APP_KEY.startsWith("CHANGE") ||
                APP_SECRET.startsWith("CHANGE")) {
            showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the DBRoulette ap before trying it.");
            finish();
            return;
        }

        // Check if the app has set up its manifest properly.
        Intent testIntent = new Intent(Intent.ACTION_VIEW);
        String scheme = "db-" + APP_KEY;
        String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
        testIntent.setData(Uri.parse(uri));
        PackageManager pm = getPackageManager();
        if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
            showToast("URL scheme in your app's " +
                    "manifest is not set up correctly. You should have a " +
                    "com.dropbox.client2.android.AuthActivity with the " +
                    "scheme: " + scheme);
            finish();
        }
    }

    private void showToast(String msg) {
        Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
        error.show();
    }

    /**
     * Shows keeping the access keys returned from Trusted Authenticator in a local
     * store, rather than storing user name & password, and re-authenticating each
     * time (which is not to be done, ever).
     *
     * @return Array of [access_key, access_secret], or null if none stored
     */
    private String[] getKeys() {
        SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
        String key = prefs.getString(ACCESS_KEY_NAME, null);
        String secret = prefs.getString(ACCESS_SECRET_NAME, null);
        if (key != null && secret != null) {
        	String[] ret = new String[2];
        	ret[0] = key;
        	ret[1] = secret;
        	return ret;
        } else {
        	return null;
        }
    }

    /**
     * Shows keeping the access keys returned from Trusted Authenticator in a local
     * store, rather than storing user name & password, and re-authenticating each
     * time (which is not to be done, ever).
     */
    private void storeKeys(String key, String secret) {
        // Save the access key for later
        SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
        Editor edit = prefs.edit();
        edit.putString(ACCESS_KEY_NAME, key);
        edit.putString(ACCESS_SECRET_NAME, secret);
        edit.commit();
    }

    private void clearKeys() {
        SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
        Editor edit = prefs.edit();
        edit.clear();
        edit.commit();
    }

    private AndroidAuthSession buildSession() {
        AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
        AndroidAuthSession session;

        String[] stored = getKeys();
        if (stored != null) {
            AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
            session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken);
        } else {
            session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE);
        }

        return session;
    }
}